﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Pavilion.DesignerTool
{
    /// <summary>
    /// Interaction logic for FrameRange.xaml
    /// </summary>
    public partial class FrameRange : UserControl
    {
        public static readonly DependencyProperty CurrentIndexProperty = DependencyProperty.Register("CurrentIndex", typeof(int), typeof(FrameRange),
            new PropertyMetadata(new PropertyChangedCallback(IndexChanged)));
        public static readonly DependencyProperty LeftIndexBoundsProperty = DependencyProperty.Register("LeftIndexBounds", typeof(int), typeof(FrameRange),
            new PropertyMetadata(new PropertyChangedCallback(IndexChanged)));
        public static readonly DependencyProperty RightIndexBoundsProperty = DependencyProperty.Register("RightIndexBounds", typeof(int), typeof(FrameRange),
            new PropertyMetadata(new PropertyChangedCallback(IndexChanged)));

        public const int IndexWidth = 13;
        private const int StartPosition = 4;
        public FrameRange()
        {
            InitializeComponent();
        }

        private string GenerateRulerPath()
        {
            int count = 0;
            int yPos = 25;
            int verticalYPos = 18;
            string path = "";

            for (int xPos = StartPosition; xPos < rulerCanvas.ActualWidth; xPos += IndexWidth)
            {
                if (count == 5)
                {
                    path += "M" + xPos + "," + yPos + "V" + (verticalYPos - 5);
                    count = 0;
                }
                else
                {
                    path += "M" + xPos + "," + yPos + "V" + verticalYPos;
                    count++;
                }
            }

            return path;
        }

        private void UpdateIndexLocations()
        {
            rulerLine.X1 = DeterminePositionOfIndexCentered(CurrentIndex);
            Canvas.SetLeft(rightGrid, DeterminePositionOfIndexRight(CurrentIndex + RightIndexBounds, rightGrid.ActualWidth));
            Canvas.SetLeft(leftGrid, DeterminePositionOfIndex(CurrentIndex - LeftIndexBounds));
        }

        private int DetermnineIndexByPosition(double position)
        {
            return (int)((position - StartPosition) / IndexWidth);
        }

        private double DeterminePositionOfIndex(int index)
        {
            if (index < 0)
                index = 0;

            return index * IndexWidth + StartPosition;
        }

        private double DeterminePositionOfIndexCentered(int index)
        {
            return DeterminePositionOfIndex(index) + (IndexWidth / 2);
        }

        private double DeterminePositionOfIndexRight(int index, double contentWidth)
        {
            return DeterminePositionOfIndex(index) + IndexWidth - contentWidth;
        }
        
        public int CurrentIndex
        {
            get { return (int)GetValue(CurrentIndexProperty); }
            set { SetValue(CurrentIndexProperty, value); }
        }

        public int LeftIndexBounds
        {
            get { return (int)GetValue(LeftIndexBoundsProperty); }
            set
            {
                if (value < 0)
                    SetValue(LeftIndexBoundsProperty, 0);
                else
                    SetValue(LeftIndexBoundsProperty, value);
            }
        }

        public int RightIndexBounds
        {
            get { return (int)GetValue(RightIndexBoundsProperty); }
            set
            {
                if (value < 0)
                    SetValue(RightIndexBoundsProperty, 0);
                else
                    SetValue(RightIndexBoundsProperty, value);
            }
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            rulerPath.Data = Geometry.Parse(GenerateRulerPath());
            base.OnRender(drawingContext);
        }

        private void RulerCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (leftGridSelected)
                LeftIndexBounds = CurrentIndex - DetermnineIndexByPosition(Mouse.GetPosition(rulerCanvas).X);
            else if (rightGridSelected)
                RightIndexBounds = DetermnineIndexByPosition(Mouse.GetPosition(rulerCanvas).X) - CurrentIndex;
        }

        private bool leftGridSelected;
        private void LeftGrid_MouseDown(object sender, MouseButtonEventArgs e) { leftGridSelected = true; }
        private void LeftGrid_MouseUp(object sender, MouseButtonEventArgs e) { leftGridSelected = false; }

        private bool rightGridSelected;
        private void RightGrid_MouseDown(object sender, MouseButtonEventArgs e) { rightGridSelected = true; }
        private void RightGrid_MouseUp(object sender, MouseButtonEventArgs e) { rightGridSelected = false; }

        private void RulerCanvas_MouseUp(object sender, MouseButtonEventArgs e)
        {
            rightGridSelected = false;
            leftGridSelected = false;
        }

        private void RulerCanvas_MouseLeave(object sender, MouseEventArgs e)
        {
            rightGridSelected = false;
            leftGridSelected = false;
        }

        static private void IndexChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
        {
            ((FrameRange)dependencyObject).UpdateIndexLocations();
        }
    }
}
